#ifndef _S_API_STRUCT_H_
#define _S_API_STRUCT_H_

#include "U_api_Types.h"
#include "E_api_Enum.h"

struct S_api_BufferDesc
{
	i32														ByteWidth;
	E_api_Usage										Usage;
	E_api_Bind_Flag								BindFlags;
	E_api_Cpu_Access_Flag					CPUAccessFlags;
	E_api_Resource_Misc_Flag			MiscFlags;

	S_api_BufferDesc();
};

struct S_api_Subresource_Data
{
	void												*	pSysMem;
	u32														SysMemPitch;
	u32														SysMemSlicePitch;

	E_api_Format									Format;

	S_api_Subresource_Data();
};

struct S_api_Shader_Macro 
{
	char												*	Name;
	char												*	Definition;
	S_api_Shader_Macro();
};

struct S_api_Input_Element_Desc
{
	char												*	SemanticName;
	i32														SemanticIndex;
	E_api_Format									Format;
	i32														InputSlot;
	i32														AlignedByteOffset;
	E_api_Input_Classification		InputSlotClass;
	i32														InstanceDataStepRate;
	S_api_Input_Element_Desc();
};

struct S_api_Sample_Desc
{
	u32														Count;
	u32														Quality;
};

struct S_api_Texture2D_Desc
{
	u32														Width;
	u32														Height;
	u32														MipLevels;
	u32														ArraySize;
	E_api_Format									Format;
	S_api_Sample_Desc							SampleDesc;
	E_api_Usage										Usage;
	u32														BindFlags;
	u32														CPUAccessFlags;
	u32														MiscFlags;

	S_api_Texture2D_Desc()
	{
		Width = 0;
		Height = 0;
		MipLevels = 1;
		ArraySize = 1;
		Format = E_api_Format_unknown;
		SampleDesc.Count = 0;
		SampleDesc.Quality = 0;
		Usage = E_api_Usage_Default;
		BindFlags = 0;
		CPUAccessFlags = 0;
		MiscFlags = 0;
	}
};

struct S_api_Mapped_Texture2D
{
	void												*	pData;
	u32														RowPitch;
};

struct S_api_Buffer_RTV 
{
	u32														ElementOffset;
	u32														ElementWidth;
};

struct S_api_Tex1d_RTV 
{
	u32														MipSlice;
};

struct S_api_Tex1d_Array_RTV 
{
	u32														MipSlice;
	u32														FirstArraySlice;
	u32														ArraySize;
};

struct S_api_Tex2d_RTV 
{
	u32														MipSlice;
};

struct S_api_Tex2d_Array_RTV 
{
	u32														MipSlice;
	u32														FirstArraySlice;
	u32														ArraySize;
};

struct S_api_Tex2dms_RTV 
{
	u32														UnusedField_NothingToDefine;
};

struct S_api_Tex2dms_Array_RTV 
{
	u32														FirstArraySlice;
	u32														ArraySize;
};

struct S_api_Tex3d_RTV 
{
	u32														MipSlice;
	u32														FirstWSlice;
	u32														WSize;
};


struct S_api_RenderTargetView_Desc
{	
		E_api_Format								Format;
		E_api_RTV_Dimension					ViewDimension;
		union 
		{
			S_api_Buffer_RTV					Buffer;
			S_api_Tex1d_RTV						Texture1D;
			S_api_Tex1d_Array_RTV			Texture1DArray;
			S_api_Tex2d_RTV						Texture2D;
			S_api_Tex2d_Array_RTV			Texture2DArray;
			S_api_Tex2dms_RTV					Texture2DMS;
			S_api_Tex2dms_Array_RTV		Texture2DMSArray;
			S_api_Tex3d_RTV						Texture3D;
		};
};

struct S_api_Tex1d_DSV 
{
	u32														MipSlice;
};

struct S_api_Tex1d_Array_DSV 
{
	u32														MipSlice;
	u32														FirstArraySlice;
	u32														ArraySize;
};

struct S_api_Tex2d_DSV 
{
	u32														MipSlice;
};

struct S_api_Tex2d_Array_DSV 
{
	u32														MipSlice;
	u32														FirstArraySlice;
	u32														ArraySize;
};

struct S_api_Tex2dms_DSV 
{
	u32														UnusedField_NothingToDefine;
};

struct S_api_Tex2dms_Array_DSV 
{
	u32														FirstArraySlice;
	u32														ArraySize;
};

struct S_api_DepthStencilView_Desc
{
	E_api_Format									Format;
	E_api_DSV_Dimension						ViewDimension;
	union 
	{
		S_api_Tex1d_DSV							Texture1D;
		S_api_Tex1d_Array_DSV				Texture1DArray;
		S_api_Tex2d_DSV							Texture2D;
		S_api_Tex2d_Array_DSV				Texture2DArray;
		S_api_Tex2dms_DSV						Texture2DMS;
		S_api_Tex2dms_Array_DSV			Texture2DMSArray;
	};
};

struct S_api_Buffer_SRV 
{
	u32														ElementOffset;
	u32														ElementWidth;
};

struct S_api_Tex1d_SRV 
{
	u32														MostDetailedMip;
	u32														MipLevels;
};

struct S_api_Tex1d_Array_SRV 
{
	u32														MostDetailedMip;
	u32														MipLevels;
	u32														FirstArraySlice;
	u32														ArraySize;
};

struct S_api_Tex2d_SRV 
{
	u32														MostDetailedMip;
	u32														MipLevels;
};

struct S_api_Tex2d_Array_SRV 
{
	u32														MostDetailedMip;
	u32														MipLevels;
	u32														FirstArraySlice;
	u32														ArraySize;
};

struct S_api_Tex2dms_SRV 
{
	u32														UnusedField_NothingToDefine;
};

struct S_api_Tex2dms_Array_SRV 
{
	u32														FirstArraySlice;
	u32														ArraySize;
};

struct S_api_Tex3d_SRV
{
	u32														MostDetailedMip;
	u32														MipLevels;
} ;

struct S_api_Texcube_SRV
{
	u32														MostDetailedMip;
	u32														MipLevels;
};

struct S_api_ShaderResourceView_Desc 
{
	E_api_Format Format;
	E_api_SRV_Dimension ViewDimension;
	union 
	{
		S_api_Buffer_SRV Buffer;
		S_api_Tex1d_SRV Texture1D;
		S_api_Tex1d_Array_SRV Texture1DArray;
		S_api_Tex2d_SRV Texture2D;
		S_api_Tex2d_Array_SRV Texture2DArray;
		S_api_Tex2dms_SRV Texture2DMS;
		S_api_Tex2dms_Array_SRV Texture2DMSArray;
		S_api_Tex3d_SRV Texture3D;
		S_api_Texcube_SRV TextureCube;
	};
};

enum E_api_UAV_Dimension
{
	E_api_UAV_Dimension_Unknown = 0,
	E_api_UAV_Dimension_Buffer = 1,
	E_api_UAV_Dimension_Texture1d = 2,
	E_api_UAV_Dimension_Texture1dArray = 3,
	E_api_UAV_Dimension_Texture2d = 4,
	E_api_UAV_Dimension_Texture2dArray = 5,
	E_api_UAV_Dimension_Texture3d = 8,
};

struct E_api_Buffer_UAV 
{
	u32 FirstElement;
	u32 NumElements;
	u32 Flags;
};

struct E_api_Tex1d_UAV 
{
	u32 MipSlice;
};

struct E_api_Tex1d_Array_UAV 
{
	u32 MipSlice;
	u32 FirstArraySlice;
	u32	ArraySize;
};

struct E_api_Tex2d_UAV 
{
	u32 MipSlice;
};

struct E_api_Tex2d_Array_UAV 
{
	u32 MipSlice;
	u32 FirstArraySlice;
	u32 ArraySize;
};

struct E_api_Tex3d_UAV 
{
	u32 MipSlice;
	u32 FirstWSlice;
	u32 WSize;
};

struct S_api_UnorderedAccessView_Desc
{
	E_api_Format Format;
	E_api_UAV_Dimension ViewDimension;
	union 
	{
		E_api_Buffer_UAV Buffer;
		E_api_Tex1d_UAV Texture1D;
		E_api_Tex1d_Array_UAV Texture1DArray;
		E_api_Tex2d_UAV Texture2D;
		E_api_Tex2d_Array_UAV Texture2DArray;
		E_api_Tex3d_UAV Texture3D;
	};
};

struct S_api_Rasterizer_Desc 
{
	E_api_Fill_Mode		FillMode;
	E_api_Cull_Mode		CullMode;
	bool							FrontCounterClockwise;
	i32								DepthBias;
	float							DepthBiasClamp;
	float							SlopeScaledDepthBias;
	bool							DepthClipEnable;
	bool							ScissorEnable;
	bool							MultisampleEnable;
	bool							AntialiasedLineEnable;
	S_api_Rasterizer_Desc()
	{
		FillMode = E_api_Fill_Solid;
		CullMode = E_api_Cull_Back;
		FrontCounterClockwise = true;
		DepthBias = 0;
		DepthBiasClamp = 0.0f;
		SlopeScaledDepthBias = 0.0f;
		DepthClipEnable = false;
		ScissorEnable = false;
		MultisampleEnable = false;
		AntialiasedLineEnable = false;
	}
};

struct S_api_Depth_Stencilop_Desc
{
	E_api_Stencil_Op						StencilFailOp;
	E_api_Stencil_Op						StencilDepthFailOp;
	E_api_Stencil_Op						StencilPassOp;
	E_api_Comparison_Func				StencilFunc;
	S_api_Depth_Stencilop_Desc()
	{
		StencilFailOp = E_api_Stencil_Op_Keep;
		StencilDepthFailOp = E_api_Stencil_Op_Keep;
		StencilPassOp = E_api_Stencil_Op_Keep;
		StencilFunc = E_api_Comparison_Always;
	}
};

struct S_api_DepthStencilState
{
	bool												DepthEnable;
	E_api_Depth_Write_Mask			DepthWriteMask;
	E_api_Comparison_Func				DepthFunc;
	bool												StencilEnable;
	u8													StencilReadMask;
	u8													StencilWriteMask;
	S_api_Depth_Stencilop_Desc	FrontFace;
	S_api_Depth_Stencilop_Desc	BackFace;
	S_api_DepthStencilState()
	{
		DepthEnable = true;
		DepthWriteMask = E_api_Depth_Write_Mask_All;
		DepthFunc = E_api_Comparison_Less;
		StencilEnable = false;
		StencilReadMask = 0;
		StencilWriteMask = 0;
		FrontFace = S_api_Depth_Stencilop_Desc();
		BackFace = S_api_Depth_Stencilop_Desc();
	}

};

#endif